package test.lemonyfei.http.desk;

import test.lemonyfei.http.utils.FileUtils;
import test.lemonyfei.http.utils.HttpContext;
import test.lemonyfei.http.utils.HttpMockServer;
import test.lemonyfei.http.view.HelpDialog;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * Created by sh00556 on 2017/4/25.
 */
public class MainInterface extends JFrame {
    private static final long serialVersionUID = 1L;
    private static final String configFileName = "src\\main\\resources\\HttpMockServerTool.config";
    private static final int numberOfConfigTableLines = 9;
    private JTextField textOfPort;
    private JTable urlsTable;
    private JButton startButton;
    private JButton stopButton;
    private JButton rebootButton;
    private JTextArea areaOfConsole;
    private HttpMockServer httpMockServer;
    private JComboBox<Object> comboBoxOfServerType;
    private JComboBox<Object> comboBoxOfProtocolType;

    public MainInterface() {
        initFrame();
        initMenuBar();
        initLayout();
    }

    public static void main(String[] args) {
        MainInterface mainInterface = new MainInterface();
        mainInterface.setDefaultCloseOperation(3);
        mainInterface.setVisible(true);
    }

    private void initFrame() {
        try {
            UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        SwingUtilities.updateComponentTreeUI(this);
        Toolkit kit = Toolkit.getDefaultToolkit();
        Dimension screenSize = kit.getScreenSize();
        int screenHeight = screenSize.height;
        int screenWidth = screenSize.width;
        setResizable(false);
        setSize(800, 600);
        setLocation(screenWidth * 1 / 8, screenHeight * 1 / 8);
        setTitle("HttpMockServerTool (v1.1)");
    }

    private void initMenuBar() {
        JMenuBar menuBar = new JMenuBar();
        menuBar.add(Box.createRigidArea(new Dimension(0, 25)));
        setJMenuBar(menuBar);
        JMenu fileMenu = new JMenu("帮助");
        menuBar.add(fileMenu);
        JMenuItem helpItem = new JMenuItem("帮助");
        helpItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                HelpDialog dialog = new HelpDialog(MainInterface.this);
                dialog.setVisible(true);
            }
        });
        fileMenu.add(helpItem);
    }

    private void initLayout() {
        JPanel jpanel = new JPanel();
        add(jpanel);
        JPanel portConfigPanel = initPortJPanel();
        JPanel configPanel = initConfigJPanel();
        JPanel consolePanel = initConsoleJPanel();
        jpanel.add(portConfigPanel);
        jpanel.add(configPanel);
        jpanel.add(consolePanel);
    }

    private JPanel initPortJPanel() {
        JPanel portConfigPanel = new JPanel();
        portConfigPanel.setLayout(new BorderLayout());
        portConfigPanel.setBorder(BorderFactory.createTitledBorder("端口设置&服务端类型&加密协议类型"));
        portConfigPanel.setPreferredSize(new Dimension(800, 45));

        JPanel settings = new JPanel();
        settings.setLayout(new GridLayout(1, 3));
        this.textOfPort = new JTextField();
        settings.add(this.textOfPort);
        String[] serverTypeStrings = {"HTTP", "HTTPS"};
        this.comboBoxOfServerType = new JComboBox(serverTypeStrings);
        settings.add(this.comboBoxOfServerType);
        String[] protocolTypeStrings = {"SSL", "SSLv2", "SSLv3", "TLS", "TLSv1", "TLSv1.1", "TLSv1.2"};
        this.comboBoxOfProtocolType = new JComboBox(protocolTypeStrings);
        settings.add(this.comboBoxOfProtocolType);
        portConfigPanel.add(settings, "North");

        return portConfigPanel;
    }

    private JPanel initConfigJPanel() {
        JPanel configPanel = new JPanel();
        configPanel.setLayout(new BorderLayout());
        configPanel.setBorder(BorderFactory.createTitledBorder("URL和response文件路径设置"));
        configPanel.setPreferredSize(new Dimension(800, 200));
        Object[][] urlsAndPaths = initConfigTableData();
        String[] columnName = {"URL", "response文件路径"};
        this.urlsTable = new JTable(urlsAndPaths, columnName);
        this.urlsTable.putClientProperty("terminateEditOnFocusLost", Boolean.valueOf(true));
        configPanel.add(new JScrollPane(this.urlsTable));
        return configPanel;
    }

    private JPanel initConsoleJPanel() {
        JPanel consolePanel = new JPanel();
        consolePanel.setLayout(new BorderLayout());
        consolePanel.setBorder(BorderFactory.createTitledBorder("控制台"));
        consolePanel.setPreferredSize(new Dimension(800, 290));
        JPanel buttons = new JPanel();
        buttons.setLayout(new GridLayout(1, 3));
        this.startButton = new JButton("启动");
        this.stopButton = new JButton("停止");
        this.rebootButton = new JButton("重新加载");
        buttons.add(this.startButton);
        buttons.add(this.stopButton);
        buttons.add(this.rebootButton);
        consolePanel.add(buttons, "North");
        this.areaOfConsole = new JTextArea();
        this.areaOfConsole.setEditable(false);
        this.areaOfConsole.setLineWrap(true);
        consolePanel.add(new JScrollPane(this.areaOfConsole));
        final JPopupMenu clearConsoleMenu = new JPopupMenu();
        JMenuItem itemOfClearConsole = new JMenuItem("清空");
        clearConsoleMenu.add(itemOfClearConsole);
        this.startButton.addActionListener(new StartListener());
        this.stopButton.addActionListener(new StopListener());
        this.rebootButton.addActionListener(new RebootListener());
        itemOfClearConsole.addActionListener(new ClearListener());

        this.areaOfConsole.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent event) {
                triggerEvent(event);
            }

            public void mouseReleased(MouseEvent event) {
                triggerEvent(event);
            }

            private void triggerEvent(MouseEvent event) {
                if (event.isPopupTrigger()) {
                    clearConsoleMenu.show(event.getComponent(), event.getX(), event.getY());
                }
            }
        });
        this.areaOfConsole.setComponentPopupMenu(clearConsoleMenu);
        return consolePanel;
    }

    private void startListener() {
        ArrayList<String> configData = new ArrayList();
        this.httpMockServer = new HttpMockServer();
        if (this.comboBoxOfServerType.getSelectedItem().equals("HTTP")) {
            this.httpMockServer.initServer(Integer.valueOf(this.textOfPort.getText()).intValue());
        } else {
            this.httpMockServer.initServer(Integer.valueOf(this.textOfPort.getText()).intValue(), (String) this.comboBoxOfProtocolType.getSelectedItem());
        }
        for (int i = 0; i < 9; i++) {
            String url = (String) this.urlsTable.getValueAt(i, 0);
            if ((url != null) && (!url.equals(""))) {
                String path = (String) this.urlsTable.getValueAt(i, 1);
                if (!path.equals("")) {
                    HttpContext httpContext = new HttpContext();
                    httpContext.setResultCode(Integer.valueOf(FileUtils.readFirstLineOfFile(path)).intValue());
                    httpContext.setResponseBody(FileUtils.readFileWithoutFirstLine(path));
                    httpContext.setUrl(url);
                    httpContext.setHeaders(null);
                    httpContext.setRequestParams("");
                    httpContext.setAreaOfConsole(this.areaOfConsole);
                    this.httpMockServer.createContext(httpContext);
                }
                configData.add(url + "," + path);
            }
        }
        this.httpMockServer.startServer();
        if (this.comboBoxOfServerType.getSelectedItem().equals("HTTP")) {
            this.areaOfConsole.append("HTTP Server启动成功，端口为" + this.textOfPort.getText() + "。\n");
        } else {
            this.areaOfConsole.append("HTTPS Server启动成功，端口为" + this.textOfPort.getText() + "，" +
                    "加密协议为" + this.comboBoxOfProtocolType.getSelectedItem() + "。\n");
        }
        if (configData != null) {
            try {
                PrintWriter writer = new PrintWriter(configFileName, "UTF-8");
                for (int i = 0; i < configData.size(); i++) {
                    writer.println(configData.get(i));
                }
                writer.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void stopListener() {
        this.httpMockServer.stop();
        this.areaOfConsole.append("HttpMockServer停止。\n");
    }

    private void rebootListener() {
        stopListener();
        startListener();
    }

    private Object[][] initConfigTableData() {
        Object[][] urlsAndPaths = new Object[9][2];
        ArrayList<String> configLines = FileUtils.readConfigFile(configFileName);
        if (configLines != null) {
            int sizeOfTable = configLines.size();
            if (sizeOfTable > 9) {
                sizeOfTable = 9;
            }
            for (int i = 0; i < sizeOfTable; i++) {
                String configLine = configLines.get(i);
                String[] urlAndPath = configLine.split(",");
                urlsAndPaths[i][0] = urlAndPath[0];
                urlsAndPaths[i][1] = urlAndPath[1];
            }
        }
        return urlsAndPaths;
    }

    private class StartListener implements ActionListener {
        private StartListener() {
        }

        public void actionPerformed(ActionEvent e) {
            MainInterface.this.startListener();
        }
    }

    private class StopListener implements ActionListener {
        private StopListener() {
        }

        public void actionPerformed(ActionEvent e) {
            MainInterface.this.stopListener();
        }
    }

    private class RebootListener implements ActionListener {
        private RebootListener() {
        }

        public void actionPerformed(ActionEvent e) {
            MainInterface.this.rebootListener();
        }
    }

    private class ClearListener implements ActionListener {
        private ClearListener() {
        }

        public void actionPerformed(ActionEvent e) {
            MainInterface.this.areaOfConsole.setText("");
        }
    }
}
